#
# Copyright 2008 Charles Connell <charles@connells.org>
#
# This file is part of Tuxedo.
#
# Tuxedo is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Tuxedo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Tuxedo; if not, see <http://gnu.org/licenses/.>
#

import os
import ConfigParser
import task
import statusconfig

# Constant for path of configuration file
CONFIGPATH = os.path.join(os.path.expanduser('~'), '.tuxedo_config')

class Config:
    """Abstraction of config file, accessed through ConfigParser. This is a singleton class; initizalize to use it"""
    # storage for the instance reference
    __instance = None

    def __init__(self):
        """ Create singleton instance """
        # Check whether we already have an instance
        if Config.__instance is None:
            # Create and remember instance
            Config.__instance = Config.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_Config__instance'] = Config.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)

    class __impl:
        """ Implementation of the singleton interface """
        def __init__(self):
            """Initializes default values and reads from config file the real values."""
            self.config = ConfigParser.ConfigParser()

            self.config.add_section('priority_colors')
            self.config.set('priority_colors', 'lowest', '#9999FF')
            self.config.set('priority_colors', 'low', '#CCCCFF')
            self.config.set('priority_colors', 'normal', '#FFFFFF')
            self.config.set('priority_colors', 'high', '#FFAAAA')
            self.config.set('priority_colors', 'highest', '#FF4444')

            self.config.add_section('text_colors')
            self.config.set('text_colors', 'lowest', '#000000')
            self.config.set('text_colors', 'low', '#000000')
            self.config.set('text_colors', 'normal', '#000000')
            self.config.set('text_colors', 'high', '#000000')
            self.config.set('text_colors', 'highest', '#000000')

            self.config.add_section('priority_names')
            self.config.set('priority_names', 'lowest', 'Lowest')
            self.config.set('priority_names', 'low', 'Low')
            self.config.set('priority_names', 'normal', 'Normal')
            self.config.set('priority_names', 'high', 'High')
            self.config.set('priority_names', 'highest', 'Highest')

            self.config.add_section('status_names')
            self.config.set('status_names', 'not_started', 'Not Started')
            self.config.set('status_names', 'in_progress', 'In Progress')
            self.config.set('status_names', 'completed', 'Completed')

            self.config.add_section('status_options_not_started')
            self.config.set('status_options_not_started', 'bold', 'no')
            self.config.set('status_options_not_started', 'italic', 'no')
            self.config.set('status_options_not_started', 'underline', 'no')
            self.config.set('status_options_not_started', 'strikethrough', 'no')

            self.config.add_section('status_options_in_progress')
            self.config.set('status_options_in_progress', 'bold', 'no')
            self.config.set('status_options_in_progress', 'italic', 'yes')
            self.config.set('status_options_in_progress', 'underline', 'no')
            self.config.set('status_options_in_progress', 'strikethrough', 'no')

            self.config.add_section('status_options_completed')
            self.config.set('status_options_completed', 'bold', 'no')
            self.config.set('status_options_completed', 'italic', 'no')
            self.config.set('status_options_completed', 'underline', 'no')
            self.config.set('status_options_completed', 'strikethrough', 'yes')

            self.config.read(CONFIGPATH)

        def priorityColors(self):
            """Make list of colors from config backend and return it."""
            prioritycolors = [None]*5
            prioritycolors[task.TASK_PRIORITY_LOWEST] = self.config.get('priority_colors', 'lowest')
            prioritycolors[task.TASK_PRIORITY_LOW] = self.config.get('priority_colors', 'low')
            prioritycolors[task.TASK_PRIORITY_NORMAL] = self.config.get('priority_colors', 'normal')
            prioritycolors[task.TASK_PRIORITY_HIGH] = self.config.get('priority_colors', 'high')
            prioritycolors[task.TASK_PRIORITY_HIGHEST] = self.config.get('priority_colors', 'highest')
            return prioritycolors

        def setPriorityColors(self, prioritycolors):
            """Copy colors into config backend."""
            self.config.set('priority_colors', 'lowest', prioritycolors[task.TASK_PRIORITY_LOWEST])
            self.config.set('priority_colors', 'low', prioritycolors[task.TASK_PRIORITY_LOW])
            self.config.set('priority_colors', 'normal', prioritycolors[task.TASK_PRIORITY_NORMAL])
            self.config.set('priority_colors', 'high', prioritycolors[task.TASK_PRIORITY_HIGH])
            self.config.set('priority_colors', 'highest', prioritycolors[task.TASK_PRIORITY_HIGHEST])

        def textColors(self):
            """Make list of colors from config backend and return it."""
            textcolors = [None]*5
            textcolors[task.TASK_PRIORITY_LOWEST] = self.config.get('text_colors', 'lowest')
            textcolors[task.TASK_PRIORITY_LOW] = self.config.get('text_colors', 'low')
            textcolors[task.TASK_PRIORITY_NORMAL] = self.config.get('text_colors', 'normal')
            textcolors[task.TASK_PRIORITY_HIGH] = self.config.get('text_colors', 'high')
            textcolors[task.TASK_PRIORITY_HIGHEST] = self.config.get('text_colors', 'highest')
            return textcolors

        def setTextColors(self, textcolors):
            """Copy colors into config backend."""
            self.config.set('text_colors', 'lowest', textcolors[task.TASK_PRIORITY_LOWEST])
            self.config.set('text_colors', 'low', textcolors[task.TASK_PRIORITY_LOW])
            self.config.set('text_colors', 'normal', textcolors[task.TASK_PRIORITY_NORMAL])
            self.config.set('text_colors', 'high', textcolors[task.TASK_PRIORITY_HIGH])
            self.config.set('text_colors', 'highest', textcolors[task.TASK_PRIORITY_HIGHEST])

        def priorityNames(self):
            """Make list of names from config backend and return it."""
            prioritynames = [None]*5
            prioritynames[task.TASK_PRIORITY_LOWEST] = self.config.get('priority_names', 'lowest')
            prioritynames[task.TASK_PRIORITY_LOW] = self.config.get('priority_names', 'low')
            prioritynames[task.TASK_PRIORITY_NORMAL] = self.config.get('priority_names', 'normal')
            prioritynames[task.TASK_PRIORITY_HIGH] = self.config.get('priority_names', 'high')
            prioritynames[task.TASK_PRIORITY_HIGHEST] = self.config.get('priority_names', 'highest')
            return prioritynames

        def setPriorityNames(self, prioritynames):
            """Copy names into config backend."""
            self.config.set('priority_names', 'lowest', prioritynames[task.TASK_PRIORITY_LOWEST])
            self.config.set('priority_names', 'low', prioritynames[task.TASK_PRIORITY_LOW])
            self.config.set('priority_names', 'normal', prioritynames[task.TASK_PRIORITY_NORMAL])
            self.config.set('priority_names', 'high', prioritynames[task.TASK_PRIORITY_HIGH])
            self.config.set('priority_names', 'highest', prioritynames[task.TASK_PRIORITY_HIGHEST])

        def statusNames(self):
            """Make list of names from config backend and return it."""
            statusnames = [None]*3
            statusnames[task.TASK_NOTSTARTED] = self.config.get('status_names', 'not_started')
            statusnames[task.TASK_INPROGRESS] = self.config.get('status_names', 'in_progress')
            statusnames[task.TASK_COMPLETED] = self.config.get('status_names', 'completed')
            return statusnames

        def setStatusNames(self, statusnames):
            """Copy names into config backend."""
            self.config.set('status_names', 'not_started', statusnames[task.TASK_NOTSTARTED])
            self.config.set('status_names', 'in_progress', statusnames[task.TASK_INPROGRESS])
            self.config.set('status_names', 'completed', statusnames[task.TASK_COMPLETED])

        def setStatusOptions(self, statusoptions):
            """Copy options into config backend."""

            # Make local copy of statusoptions
            options = []
            for l in statusoptions:
                options.append(list(l))

            # Scan through each item in 2D array options. Convert each item from boolean to string
            for i, l in enumerate(options):
                for j, o in enumerate(l):
                    if l[j] == True:
                        l[j] = 'yes'
                    else:
                        l[j] = 'no'

            # Set options in config backend
            self.config.set('status_options_not_started', 'bold', options[task.TASK_NOTSTARTED][statusconfig.STATUS_BOLD])
            self.config.set('status_options_not_started', 'italic', options[task.TASK_NOTSTARTED][statusconfig.STATUS_ITALIC])
            self.config.set('status_options_not_started', 'underline', options[task.TASK_NOTSTARTED][statusconfig.STATUS_UNDERLINE])
            self.config.set('status_options_not_started', 'strikethrough', options[task.TASK_NOTSTARTED][statusconfig.STATUS_STRIKETHROUGH])

            self.config.set('status_options_in_progress', 'bold', options[task.TASK_INPROGRESS][statusconfig.STATUS_BOLD])
            self.config.set('status_options_in_progress', 'italic', options[task.TASK_INPROGRESS][statusconfig.STATUS_ITALIC])
            self.config.set('status_options_in_progress', 'underline', options[task.TASK_INPROGRESS][statusconfig.STATUS_UNDERLINE])
            self.config.set('status_options_in_progress', 'strikethrough', options[task.TASK_INPROGRESS][statusconfig.STATUS_STRIKETHROUGH])

            self.config.set('status_options_completed', 'bold', options[task.TASK_COMPLETED][statusconfig.STATUS_BOLD])
            self.config.set('status_options_completed', 'italic', options[task.TASK_COMPLETED][statusconfig.STATUS_ITALIC])
            self.config.set('status_options_completed', 'underline', options[task.TASK_COMPLETED][statusconfig.STATUS_UNDERLINE])
            self.config.set('status_options_completed', 'strikethrough', options[task.TASK_COMPLETED][statusconfig.STATUS_STRIKETHROUGH])

        def statusOptions(self):
            """Make list of options from config backend and return it."""
            statusoptions = [[bool, bool, bool, bool], [bool, bool, bool, bool], [bool, bool, bool, bool]]

            statusoptions[task.TASK_NOTSTARTED][statusconfig.STATUS_BOLD] = self.config.getboolean('status_options_not_started', 'bold')
            statusoptions[task.TASK_NOTSTARTED][statusconfig.STATUS_ITALIC] = self.config.getboolean('status_options_not_started', 'italic')  
            statusoptions[task.TASK_NOTSTARTED][statusconfig.STATUS_UNDERLINE] = self.config.getboolean('status_options_not_started', 'underline')
            statusoptions[task.TASK_NOTSTARTED][statusconfig.STATUS_STRIKETHROUGH] = self.config.getboolean('status_options_not_started', 'strikethrough')

            statusoptions[task.TASK_INPROGRESS][statusconfig.STATUS_BOLD] = self.config.getboolean('status_options_in_progress', 'bold')
            statusoptions[task.TASK_INPROGRESS][statusconfig.STATUS_ITALIC] = self.config.getboolean('status_options_in_progress', 'italic')
            statusoptions[task.TASK_INPROGRESS][statusconfig.STATUS_UNDERLINE] = self.config.getboolean('status_options_in_progress', 'underline')
            statusoptions[task.TASK_INPROGRESS][statusconfig.STATUS_STRIKETHROUGH] = self.config.getboolean('status_options_in_progress', 'strikethrough')

            statusoptions[task.TASK_COMPLETED][statusconfig.STATUS_BOLD] = self.config.getboolean('status_options_completed', 'bold')
            statusoptions[task.TASK_COMPLETED][statusconfig.STATUS_ITALIC] = self.config.getboolean('status_options_completed', 'italic')
            statusoptions[task.TASK_COMPLETED][statusconfig.STATUS_UNDERLINE] = self.config.getboolean('status_options_completed', 'underline')
            statusoptions[task.TASK_COMPLETED][statusconfig.STATUS_STRIKETHROUGH] = self.config.getboolean('status_options_completed', 'strikethrough')

            return statusoptions

        def save(self):
            """Open config file and save config options to it."""
            fp = open(CONFIGPATH, 'w')
            self.config.write(fp)
            fp.close()
